﻿namespace Xbb.Common.Extension
{
    using MT.Common;
    using System;
    using System.Runtime.CompilerServices;
    using System.Threading.Tasks;
  

    public static class AsyncExtension
    {
        /// <summary>
        /// Awaits the result.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="task">The task.</param>
        /// <returns></returns>
        public static T Await<T>(this Task<T> task)
        {
           // var context = MyHttpContext.Current;
            var taskR = task.ConfigureAwait(false).GetAwaiter();
            var result = taskR.GetResult();
            //MyHttpContext.Current = context;
            return result;
        }

        /// <summary>
        /// Awaits the specified task.
        /// </summary>
        /// <param name="task">The task.</param>
        public static void Await(this Task task)
        {
            //var context = System.Web.HttpContext.Current;
            var taskWaiter = Task.Run(async () => await task).ConfigureAwait(false);
            taskWaiter.GetAwaiter().GetResult();
           // System.Web.HttpContext.Current = context;
        }

        public static async Task YieldConfigureAwait()
        {
            await Task.Run(() => { }).ConfigureAwait(false);
         }

        public static async Task InvokeMethodAsync(int retryCount, Delegate method, params object[] args)
        {
            while (true)
            {
                try
                {
                    if (method.Method.ReturnType != typeof(Task))
                    {
                        throw new ApplicationException("Method Should Return Task");
                    }

                    var task = (method.DynamicInvoke(args) as Task);
                    if (task != null)
                    {
                        await task;
                    }
                    break;
                }
                catch (Exception ex)
                {
                    retryCount--;
                    if (retryCount <= 0)
                    {
                        //ExceptionCommonLogger.LogException(e);
                        throw new Exception(ex.Message);
                    }

                }
            }
        }

        public static async Task<T> InvokeMethodAsync<T>(int retryCount, Delegate method, params object[] args)
        {
            while (true)
            {
                try
                {
                    if (method.Method.ReturnType != typeof(Task<T>))
                    {
                        throw new ApplicationException("Method Should Return Task");
                    }

                    var task = (method.DynamicInvoke(args) as Task<T>);
                    if (task != null)
                    {
                        return await task;
                    }
                }
                catch (Exception ex)
                {
                    retryCount--;
                    if (retryCount <= 0)
                    {
                        // ExceptionCommonLogger.LogException(e);
                        throw new Exception(ex.Message);
                    }
                }
            }
        }
    }
}
